package k8s

import (
	"crypto/tls"
	"crypto/x509"
	"encoding/json"
	"io"
	"log"
	"net/http"
	"net/url"
	"os"
	"time"
)

const path = "/var/run/secrets/kubernetes.io/serviceaccount"
const TOKEN = path + "/token"
const CACERT = path + "/ca.crt"
const API_SERVER = "https://kubernetes.default.svc"

func BuildRequestUrl(path string) string {
	u, err := url.Parse(API_SERVER)
	if err != nil {
		panic(err)
	}
	u = u.JoinPath(path)
	return u.String()
}

func addAuhtorizationToken(request *http.Request) {
	token, _ := os.ReadFile(TOKEN)
	log.Printf("add request token: %s\n", string(token))
	request.Header.Add("Authorization", "Bearer "+string(token))
}

func create_http_client() *http.Client {

	ca, _ := os.ReadFile(CACERT)

	log.Printf("ca: %s\n", string(ca))

	pool := x509.NewCertPool()
	pool.AppendCertsFromPEM(ca)
	tlsConfig := &tls.Config{RootCAs: pool}
	// tls.LoadX509KeyPair()
	client := &http.Client{}
	client.Transport = &http.Transport{
		TLSClientConfig: tlsConfig,
	}

	return client
}

func get_request(apiUrl string) (string, error) {
	// infoApi := API_SERVER + "/api"

	apiUrl = BuildRequestUrl(apiUrl)

	log.Printf("get request: %s\n", apiUrl)
	client := create_http_client()

	req, err := http.NewRequest("GET", apiUrl, nil)
	if err != nil {
		return "", err
	}

	addAuhtorizationToken(req)

	client.Timeout = time.Duration(10) * time.Second
	rsp, err := client.Do(req)
	if err != nil {
		return "", err
	}

	defer rsp.Body.Close()
	// 这里需要关闭client
	defer client.CloseIdleConnections()

	ret, err := io.ReadAll(rsp.Body)
	if err != nil {
		return "", err
	}

	return string(ret), nil
}

func convertResult(result string) (map[string]any, error) {
	data := map[string]any{}
	err := json.Unmarshal([]byte(result), &data)
	return data, err
}

func GetPod(namespace string) (map[string]any, error) {
	s, err := get_request("/api/v1/namespaces/" + namespace + "/pods")
	if err != nil {
		return nil, err
	}
	return convertResult(s)
}

func GetNamespaceList() (map[string]any, error) {
	s, err := get_request("/api/v1/namespaces")
	if err != nil {
		return nil, err
	}
	return convertResult(s)
}

func GetApiInfo() (map[string]any, error) {
	s, err := get_request("api")
	if err != nil {
		return nil, err
	}
	return convertResult(s)
}
